package br.ufrj.neg.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;

public class Data extends Date {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6332561087416459653L;

	/**
	 * Método Construtor sem parâmetros
	 * 
	 */
	public Data() {
		super();
	}

	/**
	 * Método Construtor, recebendo como parâmetro uma String no formato
	 * DD/MM/AAAA
	 * 
	 * @param String
	 *            data
	 */
	public Data(String data) throws Exception {
		super();
		this.setData(data);
	}
	
	public Data(String data, String hora) throws Exception {
		super();
		this.setDataHora(data, hora);
	}

	/**
	 * Método construtor, recebendo como parâmetro um java.sql.Date
	 * 
	 * @param java.sql.Date
	 *            data
	 */
	public Data(java.sql.Date sqldata) throws Exception {
		super();
		if (sqldata != null) {
			String data = sqldata.toString().substring(0,10);// formato yyyy-mm-dd
			this.setData(data);
		}
	}
	
	public Data(java.sql.Timestamp sqldata) throws Exception {
		super();
		if (sqldata != null) {
			String data = sqldata.toString();// formato yyyy-mm-dd 
			this.setDataHora(data.substring(0,10),data.substring(11,19));
		}
	}

	/**
	 * 
	 */


	/**
	 * Retorna uma String com a data no formato DD/MM/AAAA
	 * 
	 * @return String
	 */
	public String getDataBr() {
		if (this == null) return null;
		SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");
		return formato.format(this);
	}
	/**
	 * Retorna uma String com a data no formato MM/DD/AA
	 * 
	 * @return String
	 */
	public String getDataMMDDAA() {
		if (this == null) return null;
		SimpleDateFormat formato = new SimpleDateFormat("MM/dd/yy");
		return formato.format(this);
	}
	
	/**
	 * Retorna uma String com a data no formato MM/DD/AA
	 * 
	 * @return String
	 */
	public String getDataDDMMAA() {
		if (this == null) return null;
		SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yy");
		return formato.format(this);
	}
	
	/**
	 * Método para obter a data no formato "AAAA-MM-DD"
	 * 
	 * @return Uma string com valor AAAA-MM-DD
	 *           
	 */
	public String getDataAAAAMMDD() {
		if (this == null) return null;
		SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd");
		return formato.format(this);
	}
		
	/**
	 * Método para setar a data no formato "AAAA-MM-DD"
	 * 
	 * @param String
	 *            data
	 */
	public void setData(String data) throws Exception {
		GregorianCalendar gc = new GregorianCalendar();
		int i, dia, mes, ano;

		if (data.length()==0 || data==null)
			throw new Exception("Data vazia.");

		// pegar o ano
		String temp = new String();
		for (i = 0; data.charAt(i) != '-'; i++) {
			temp += data.charAt(i);
		}

		if (!isInteger(temp))
			throw new Exception("Ano não é um número válido.");

		ano = Integer.parseInt(temp);


		// pegar o mes
		temp = new String();
		for (i = i + 1; data.charAt(i) != '-'; i++) {
			temp += data.charAt(i);
		}

		if (!isInteger(temp))
			throw new Exception("Mês não é um número válido.");

		mes = Integer.parseInt(temp);

		// diminuir 1, pois janeiro eh 0
		mes--;

		if (mes < 0 || mes > 11)
			throw new Exception("Mês não é um número válido.");

		// pegar o dia
		temp = new String();
		for (i = i + 1; i < data.length(); i++) {
			temp += data.charAt(i);
		}

		if (!isInteger(temp))
			throw new Exception("Ano não é um número válido.");
		

		dia = Integer.parseInt(temp);
		
		if (dia <= 0 || dia > 31)
			throw new Exception("Dia não é um número válido.");			

		// montar data
		gc.set(ano, mes, dia);
		super.setTime(gc.getTimeInMillis());
	}	
	
	public void setDataHora(String data, String hora) throws Exception {
		GregorianCalendar gc = new GregorianCalendar();
		int i, dia, mes, ano, horaa, minuto;

		if (data == null || data.length()== 0)
			throw new Exception("Data vazia.");
		
		if (hora == null || hora.length()== 0)
			throw new Exception("Hora vazia.");
		
		// pegar o ano
		String temp = new String();
		for (i = 0; data.charAt(i) != '-'; i++) {
			temp += data.charAt(i);
		}

		if (!isInteger(temp))
			throw new Exception("Dia não é um número válido.");

		ano = Integer.parseInt(temp);

		// pegar o mes
		temp = new String();
		for (i = i + 1; data.charAt(i) != '-'; i++) {
			temp += data.charAt(i);
		}

		if (!isInteger(temp))
			throw new Exception("Mês não é um número válido.");

		mes = Integer.parseInt(temp);

		// diminuir 1, pois janeiro eh 0
		mes--;

		if (mes < 0 || mes > 11)
			throw new Exception("Mês não é um número válido.");

		// pegar o ano
		temp = new String();
		for (i = i + 1;  i < data.length(); i++) {
			temp += data.charAt(i);
		}

		if (!isInteger(temp))
			throw new Exception("Ano não é um número válido.");

		dia = Integer.parseInt(temp);
		
		if (dia <= 0 || dia > 31)
			throw new Exception("Dia não é um número válido.");
		
		/* Pega a hora*/
		temp = new String();
		for (i = 0; hora.charAt(i) != ':'; i++) {
			if( hora.charAt(i)=='T'){
				continue; /*Widget Time do dojo poe um T na frente*/
			}
			temp += hora.charAt(i);
		}
		if (!isInteger(temp))
			throw new Exception("Hora não é um número válido.");

		horaa = Integer.parseInt(temp);
		if (horaa < 0 || horaa > 23)
			throw new Exception("Hora não é um número válido.");
		
		/* Pega o minuto */
		temp = new String();
		for (i = i+1; i<hora.length() && hora.charAt(i) != ':'; i++) {
			temp += hora.charAt(i);
		}
		
		if (!isInteger(temp))
			throw new Exception("Minuto não é um número válido.");
		
		minuto = Integer.parseInt(temp);
		
		if (minuto < 00 || minuto > 59)
			throw new Exception("Minuto não é um número válido.");
		
		// montar data
		gc.set(ano, mes, dia, horaa, minuto);
		super.setTime(gc.getTimeInMillis());
	}

	/**
	 * Método para retornar a data para Banco de Dados
	 * 
	 * @return java.sql.Date
	 */
	public java.sql.Date getSQLData() {
		java.sql.Date data = new java.sql.Date(this.getTime());
		return data;
	}

	/**
	 * Método para verificar se uma String contém um Integer
	 * 
	 * @param String
	 * @return boolean
	 */
	private boolean isInteger(String s) {
		try {
			Integer.parseInt(s);
		} catch (Exception e) {
			return false;
		}
		return true;
	}
	
	@Override
	public String toString(){
		
		return getDataAAAAMMDD();
		
	}
	
	public String getHora(){
		
		if (this == null) return null;
		SimpleDateFormat formato = new SimpleDateFormat("HH:mm:ss");
		return formato.format(this);
		
	}
}
